home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
msdos
/
fractal
/
frasr182
/
fr8514a.asm
< prev
next >
Wrap
Assembly Source File
|
1992-11-17
|
51KB
|
2,066 lines
IFDEF ??version
MASM51
QUIRKS
ENDIF
.MODEL medium,c
.8086
HOPEN equ 8
HSMX equ 9
HINT equ 16
HLDPAL equ 19
HBBW equ 21
HBBR equ 23
HBBCHN equ 24
HBBC equ 25
HQMODE equ 29
HRECT equ 32
HCLOSE equ 34
HINIT equ 48
HSYNC equ 49
HSPAL equ 57
HRPAL equ 58
HLINE equ 0
HSCOL equ 7
.DATA
extrn sxdots:word, sydots:word ; number of dots across and down
extrn dacbox:byte, daccount:word
afiptr dd 0
xadj dw 0
yadj dw 0
extrn paldata:byte ; 1024-byte array (in GENERAL.ASM)
extrn stbuff:byte ; 415-byte array (in GENERAL.ASM)
linedata db 0
hopendata db 3, 0, 0, 0, 0
hclosedata dw 2, 0
hinitdata dw 2, 0
bbw dw 10, 8, 0, 1, 0, 0
bbr dw 12, 8, 0, 1, 0, 0, 0
smx dw 2, 0
chn dw 6
dd linedata
dw 1
pal dw 10, 0, 0, 256
dd paldata
hidata dw 4, 0, 8000h
amode dw 18, 9 dup(?)
hlinedata dw 8, 0, 0, 0, 0
hscoldata dw 4, 0, 0
.CODE VIDEO_TEXT
callafi proc near
push ds ; Pass the parameter pointer
push si
shl ax,1 ; form offset from entry no. required
shl ax,1
mov si,ax
les bx, afiptr ; entry block address to es:bx
call dword ptr es:[bx][si] ; call entry point
ret ; return to caller
callafi endp
getafi proc near
mov ax,357fh ; read interrupt vector 7f
int 21h
mov ax,es
or ax,bx ; is 7f vector null
stc
jz getafiret
mov ax,0105h ; get Interface address
int 7fh ; by software interrupt 7f
jc getafiret ; Interface not OK if carry set
mov word ptr afiptr,dx ; save afi pointer offset
mov word ptr afiptr+2,cx ; save afi pointer segment
clc ; clear carry flag
getafiret:
ret ; return to caller
getafi endp
do85open proc near
push ax
mov ax, HOPEN
call callafi
mov ax, offset stbuff ;get the state segment
add ax, 15
mov cl, 4
shr ax, cl
mov bx, ds
add ax, bx
mov si, offset hinitdata
mov [si] + 2, ax
pop ax
call callafi
clc
ret
do85open endp
open8514 proc near
call load8514dacbox ; load dacbox for 8514/A setup JCO 4/6/92
call getafi ;get adapter interface
jc afinotfound
mov bl, 0 ;if > 640 x 480 then 1024 x 768
mov ax, sxdots
cmp ax, 1024 ;if > 1024, don't use afi, JCO 4/4/92
ja afinotfound
cmp ax, 800 ; must be 1024
ja setupopen
cmp ax, 640 ; could be 800
ja afinotfound
mov ax, sydots
cmp ax, 480
ja setupopen
inc bl
setupopen:
mov si, offset hopendata ;open the adapter
mov byte ptr [si + 2], 40h ;zero the image but leave pallette
mov [si + 3], bl
mov ax, HINIT ;initialize state
call do85open
jc afinotfound
mov si, offset amode ;make sure on the size
mov ax, HQMODE ;get the adapter mode
call callafi
mov ax, amode + 10 ;get the screen width
cmp ax, sxdots
jae xdotsok ;check for fit
mov sxdots, ax
xdotsok:
sub ax, sxdots ;save centering factor
shr ax, 1
mov xadj, ax
mov ax, amode + 12 ;get the screen height
cmp ax, sydots
jae ydotsok
mov sydots, ax
ydotsok:
sub ax, sydots
shr ax, 1
mov yadj, ax
clc
ret
afinotfound: ; No 8514/A interface found
stc ; flag bad mode
ret ; and bail out
open8514 endp
reopen8514 proc near
mov si, offset hopendata ;open the adapter
mov byte ptr [si + 2], 0C0h ;zero the image but leave pallette
mov ax, HSYNC ;initialize state
call do85open
ret
reopen8514 endp
close8514 proc near
mov si, offset hclosedata ;turn off 8514a
mov ax, HCLOSE
call callafi
ret
close8514 endp
fr85wdotnew proc near uses si
mov byte ptr [hscoldata + 2], al
add cx, xadj
add dx, yadj
mov hlinedata + 2, cx
mov hlinedata + 4, dx
inc cx ; increment x direction
mov hlinedata + 6, cx
mov hlinedata + 8, dx
; set the color
mov si, offset hscoldata
mov ax, HSCOL
call callafi
; plot the point
mov si, offset hlinedata
mov ax, HLINE
call callafi
ret
fr85wdotnew endp
fr85wdot proc near uses si
mov linedata, al
mov bbw + 4, 1 ;define the rectangle
; mov bbw + 6, 1
add cx, xadj
add dx, yadj
mov bbw + 8, cx
mov bbw + 10, dx
mov si, offset bbw
mov ax, HBBW
call callafi
mov si, offset chn
mov word ptr [si + 2], offset linedata
mov word ptr [si + 6], 1 ;send the data
mov ax, HBBCHN
call callafi
fr85wdotx:
ret
fr85wdot endp
fr85wbox proc near uses si
sub ax, cx
inc ax ; BDT patch 11/4/90
; add ax, xadj
add cx, xadj
add dx, yadj
mov chn + 2, si ;point to data
mov chn + 6, ax
mov bbw + 4, ax ;define the rectangle
; mov bbw + 6, 1 ;set in declaration
mov bbw + 8, cx
mov bbw + 10, dx
mov si, offset bbw
mov ax, HBBW
call callafi
mov si, offset chn
mov ax, HBBCHN
call callafi
ret
fr85wbox endp
fr85rdot proc near uses si
mov bbr + 4, 1 ;define the rectangle
; mov bbr + 6, 1 ;set in declaration
add cx, xadj
add dx, yadj
mov bbr + 10, cx
mov bbr + 12, dx
mov si, offset bbr
mov ax, HBBR
call callafi
mov si, offset chn
mov word ptr [si + 2], offset linedata
mov word ptr [si + 6], 1 ;send the data
mov ax, HBBCHN
call callafi
mov al, linedata
fr85rdotx:
ret
fr85rdot endp
fr85rbox proc near uses si
sub ax, cx
inc ax ; BDT patch 11/4/90
; add ax, xadj
add cx, xadj
add dx, yadj
mov chn + 2, di ;point to data
mov chn + 6, ax
mov bbr + 4, ax ;define the rectangle
; mov bbr + 6, 1 ;set in declaration
mov bbr + 10, cx
mov bbr + 12, dx
mov si, offset bbr
mov ax, HBBR
call callafi
mov si, offset chn
mov ax, HBBCHN
call callafi
ret
fr85rbox endp
w8514pal proc near
mov si, offset dacbox
mov cx, daccount ;limit daccount to 128 to avoid fliker
cmp cx, 128
jbe countok
mov cx, 128
mov daccount, cx
countok: ;now build 8514 pallette
mov ax, 256 ;from the data in dacbox
mov pal + 4, 0
mov di, offset paldata
cld
cpallp:
push ax ;do daccount at a time
mov dx, di
cmp ax, cx
jae dopass
mov cx, ax
dopass:
mov pal + 6, cx ;entries this time
push cx
cpallp2:
push ds ;pallette format is r, b, g
pop es ;0 - 255 each
lodsb ;red
shl al, 1
shl al, 1
stosb
lodsb ;green
shl al, 1
shl al, 1
xchg ah, al
lodsb ;blue
shl al, 1
shl al, 1
stosw
mov al, 0 ;filler
stosb
loop cpallp2
push si
push di
push dx
mov si, hidata ;wait for flyback
mov ax, HINT
call callafi
pop dx
mov pal + 8, dx
mov si, offset pal ;load this piece
mov ax, HLDPAL
call callafi
pop di
pop si
pop cx
add pal + 4, cx ;increment the pallette index
pop ax
sub ax, cx
jnz cpallp
ret
w8514pal endp
;********************************************************************
;* 8514/A Hardware Interface Routines
;* Written by Aaron M. Williams for Fractint
;* This code may be used freely by anyone for anything and freely distributed.
;* All routines here are written for a V20 (80186) or better CPU.
;* All code has been at least partially optimized for a 486 (i.e. pipelining)
;* The macros were written by Roger Brown for Adex Corporation and have been
;* placed into the public domain by Adex corporation.
;*
;* Special support has been added for the Brooktree RAMDAC, which uses 8
;* bits for rgb values instead of 6 bits. This RAMDAC is used only in the
;* 1280x1024 mode (unless programmed otherwise)
;*
;* Completed on 3/8/92
;* Revised by JCO on 4/12/92
; changed width to wdth and other minor fixes so it would assemble
; using MASM 6.0
; took out duplicate variables, xadj, yadj, linedata
; took out .model C
; added VIDEO_TEXT to .code and made procedures near
; added TRANSY macro for 640x480x16 (512K), but not used
; w8514hwpal
; Changed normal 8514/A routine to slow it down
; reopen8514hw
; Renamed enableHIRES as reopen8514hw
; Commented out old reopen8514hw
; open8514hw
; Changed where board is reset so a hung board won't prevent detect of 8514/A
; Added load8514dacbox routine to initialize colors
; Added detection and setup of 512K 8514/A, use debug=8514 to test on 1 Meg
; Changed foreground mix to FSS_FRGDCOL. It's faster to use FRGD_COLOR for
; dots and set/reset the mix for boxes.
; Took out call to w8514hwpal, hangs machine if another video mode is not used
; first, load8514dacbox takes care of loading initial colors
; fr85hwwdot, fr85hwrdot
; Replaced with routines that use short stroke vectors, uses fewer port calls
; fr85hwwbox, fr85hwrbox
; Replaced with routines that use vectors
; close8514hw
; Made non-Adex 8514/A not use the enableVGA routine
; load8514dacbox
; Added this routine to load dacbox
;* Added support for ATI ULTRA 800x600x256 and 1280x1024x16 modes JCO, 11/7/92
.286 ; we use 286 code here for speed
; for in graphics, speed is everything
.DATA
; Defines
BIT_0_ON EQU 0000000000000001b
BIT_1_ON EQU 0000000000000010b
BIT_2_ON EQU 0000000000000100b
BIT_3_ON EQU 0000000000001000b
BIT_4_ON EQU 0000000000010000b
BIT_5_ON EQU 0000000000100000b
BIT_6_ON EQU 0000000001000000b
BIT_7_ON EQU 0000000010000000b
BIT_8_ON EQU 0000000100000000b
BIT_9_ON EQU 0000001000000000b
BIT_10_ON EQU 0000010000000000b
BIT_11_ON EQU 0000100000000000b
BIT_12_ON EQU 0001000000000000b
BIT_13_ON EQU 0010000000000000b
BIT_14_ON EQU 0100000000000000b
BIT_15_ON EQU 1000000000000000b
BIT_0_OFF EQU 1111111111111110b
BIT_1_OFF EQU 1111111111111101b
BIT_2_OFF EQU 1111111111111011b
BIT_3_OFF EQU 1111111111110111b
BIT_4_OFF EQU 1111111111101111b
BIT_5_OFF EQU 1111111111011111b
BIT_6_OFF EQU 1111111110111111b
BIT_7_OFF EQU 1111111101111111b
BIT_8_OFF EQU 1111111011111111b
BIT_9_OFF EQU 1111110111111111b
BIT_10_OFF EQU 1111101111111111b
BIT_11_OFF EQU 1111011111111111b
BIT_12_OFF EQU 1110111111111111b
BIT_13_OFF EQU 1101111111111111b
BIT_14_OFF EQU 1011111111111111b
BIT_15_OFF EQU 0111111111111111b
;==========================================
; Equates for use with Wait_Till_FIFO Macro
;==========================================
ONEEMPTY = BIT_7_ON
TWOEMPTY = BIT_6_ON
THREEEMPTY = BIT_5_ON
FOUREMPTY = BIT_4_ON
FIVEEMPTY = BIT_3_ON
SIXEMPTY = BIT_2_ON
SEVENEMPTY = BIT_1_ON
EIGHTEMPTY = BIT_0_ON
VSYNC_BIT_MASK = BIT_0_ON
DEFAULT_MASK = 00FFh ; Default to all 8 bits.
LOCK_FLAG = BIT_15_ON ; Flag to lock CRTC timing regs
GE_BUSY_MASK = BIT_9_ON ; Mask for GE_BUSY
GE_BUSY_SHFT = 9
MAX_RES_MASK = BIT_3_ON
MAX_RES_SHFT = 3
PATTERN_POS_MASK = (BIT_13_ON+BIT_12_ON+BIT_11_ON+BIT_10_ON+BIT_9_ON+BIT_8_ON)
PATTERN_POS_SHFT = 8
SELECT_DPAGE_2 = BIT_1_ON
SELECT_DPAGE_1 = BIT_1_OFF
SELECT_VPAGE_2 = BIT_2_ON
SELECT_VPAGE_1 = BIT_2_OFF
LOWER_12_BITS = 0FFFh ; Mask off upper 4 bits
;*****************************************************************************
;
; MACRO DEFINITIONS
;
;*****************************************************************************
;PURPOSE : Wait until there is [number] locations available in the FIFO.
Wait_Till_FIFO MACRO number
LOCAL waitfifoloop
mov dx, GP_STAT
waitfifoloop:
in ax, dx
test ax, number
jnz waitfifoloop
ENDM
; Wait if Hardware is Busy
Wait_If_HW_Busy MACRO
LOCAL waithwloop
mov dx, GP_STAT
waithwloop:
in ax, dx
test ax, FSR_HWBUSY
jnz waithwloop
ENDM
; PURPOSE: Wait Till CPU data is Available (Used for Image Read/Write)
Wait_Till_Data_Avail MACRO
LOCAL waitdataloop
mov dx, GP_STAT
waitdataloop:
in ax, dx
test ax, 0100h
jz waitdataloop
ENDM
; PURPOSE: Output a word to the specified i/o port
Out_Port MACRO port, value
IFIDNI <ax>, <value> ;; [ax] already loaded
ELSE
mov ax, value
ENDIF
IFIDNI <dx>, <port> ;; [dx] already loaded
ELSE
mov dx, port
ENDIF
out dx, ax
ENDM
; PURPOSE: Input a word from the specified i/o port
In_Port MACRO port
IFIDNI <dx>, <port> ;; [dx] already loaded
ELSE
mov dx, port
ENDIF
in ax, dx
ENDM
; PURPOSE: Output a byte to the specified i/o port
Out_Port_Byte MACRO port, value
IFIDNI <al>, <value> ;; [al] already loaded
ELSE
mov al, value
ENDIF
IFIDNI <dx>, <port> ;; [dx] already loaded
ELSE
mov dx, port
ENDIF
out dx, al
ENDM
; PURPOSE: Input a byte from the specified i/o port
In_Port_Byte MACRO port
mov dx, port ;; output contents of ax
in al, dx ;; al = value from [port]
ENDM
; PURPOSE: Wait for Vsync to go low, then high,
Wait_For_Vsync MACRO
LOCAL wait_low, wait_high
mov dx, SUBSYS_STAT
mov ax, RVBLNKFLAG
out dx, ax ; Clear Vsync status bit
wait_low:
; in ax, dx
; test ax, VSYNC_BIT_MASK
; jnz wait_low ; causes problems with ATI ********
wait_high:
in ax, dx
test ax, VSYNC_BIT_MASK
jz wait_high ; Loop until beginning of Vysnc (blank)
ENDM
; PURPOSE: Enter Western Digital Enhanced Mode.
Enter_WD_Enhanced_Mode MACRO
mov dx, WD_ESCAPE_REG
in al, dx
ENDM
; PURPOSE: Write pixel data in [ax] to PIX_TRANS port [dx]
; ENTRY : [dx] = PIX_TRANS, data in [ax]
Write_A_Pixel MACRO
Out_Port dx, ax
ENDM
; PURPOSE: Resets MULTIFUNC_CNTL register to FCOL & MIX
Reset_MULTIFUNC_CNTL MACRO
Out_Port MULTIFUNC_CNTL, 0A000h
ENDM
;
; TRANSY
;
; Translate y value for the case of 4 bpp and 640x480
; The y value is assumed to be in ax.
; The result is left in ax.
; result = (y & 1) | ((y >> 1) << 2)
; by Jonathan Osuch, 2/15/92
; Not needed by Graphics Ultra, others might need it
;
TRANSY macro
push bx
mov bx, ax
and bx, 1
shr ax, 1
shl ax, 1
shl ax, 1
or ax, bx
pop bx
endm
;
;========================================
; Return Value Definitions
;========================================
TRUE = 1
FALSE = 0
;*****************************************************************************
;
; VESA STANDARD 8514/A REGISTER MNEMONICS
;
;*****************************************************************************
;=============================
; 8514/A READBACK REGISTER SET
;=============================
SETUP_ID1 equ 00100h ; Setup Mode Identification
SETUP_ID2 equ 00101h ; Setup Mode Identification
DISP_STAT equ 002E8h ; Display Status
WD_ESCAPE_REG equ 028E9h ; WD Escape Functions
SUBSYS_STAT equ 042E8h ; Subsystem Status
WD_ENHANCED_MODE_REG equ 096E8h ; Enter WD Enhanced Mode
GP_STAT equ 09AE8h ; Graphics Processor Status
FSR_HWBUSY equ 00200h ; Bit Set if Hardware Busy
;==========================
; 8514/A WRITE REGISTER SET
;==========================
SETUP_OPT equ 00102h ; Setup Mode Option Select
H_TOTAL equ 002E8h ; Horizontal Total
DAC_MASK equ 002EAh ; DAC Mask
DAC_R_INDEX equ 002EBh ; DAC Read Index
DAC_W_INDEX equ 002ECh ; DAC Write Index
DAC_DATA equ 002EDh ; DAC Data
H_DISP equ 006E8h ; Horizontal Displayed
H_SYNC_STRT equ 00AE8h ; Horizontal Sync Start
H_SYNC_WID equ 00EE8h ; Horizontal Sync Width
V_TOTAL equ 012E8h ; Vertical Total
V_DISP equ 016E8h ; Vertical Displayed
V_SYNC_STRT equ 01AE8h ; Vertical Sync Start
V_SYNC_WID equ 01EE8h ; Vertical Sync Width
DISP_CNTL equ 022E8h ; Display Control
SUBSYS_CNTL equ 042E8h ; Subsystem Control
ICR_GERESET equ 09000h ; reset mask
ICR_NORMAL equ 08000h ; normal mask
ROM_PAGE_SEL equ 046E8h ; ROM Page Select
ADVFUNC_CNTL equ 04AE8h ; Advanced Function Control
MODE_VGA equ 00010b ;
MODE_768 equ 00111b ;
MODE_480 equ 00011b ;
CUR_Y equ 082E8h ; Current Y Position
CUR_X equ 086E8h ; Current X Position
DESTY_AXSTP equ 08AE8h ; Destination Y Position /
; Axial Step Constant
DESTX_DIASTP equ 08EE8h ; Destination X Position /
; Axial Step Constant
ERR_TERM equ 092E8h ; Error Term
MAJ_AXIS_PCNT equ 096E8h ; Major Axis Pixel Count
CMD equ 09AE8h ; Command
SHORT_STROKE equ 09EE8h ; Short Stroke Vector Trnsf
BKGD_COLOR equ 0A2E8h ; Background Color
FRGD_COLOR equ 0A6E8h ; Foreground Color
WRT_MASK equ 0AAE8h ; Write Mask
RD_MASK equ 0AEE8h ; Read Mask
COLOR_CMP equ 0B2E8h ; Color Compare
BKGD_MIX equ 0B6E8h ; Background Mix
FRGD_MIX equ 0BAE8h ; Foreground Mix
MULTIFUNC_CNTL equ 0BEE8h ; Multi-Function Control
PIX_TRANS equ 0E2E8h ; Pixel Data Transfer
MIN_AXIS_PCNT equ 0000h ; Minor Axis Pixel Count
T_SCISSORS equ 1000h ; Top Scissors
L_SCISSORS equ 2000h ; Left Scissors
B_SCISSORS equ 3000h ; Bottom Scissors
R_SCISSORS equ 4000h ; Right Scissors
MEM_CNTL equ 5000h ; Memory Control
PATTERN_L equ 8000h ; Fixed Pattern - Low
PATTERN_H equ 9000h ; Fixed Pattern - High
PIX_CNTL equ 0A000h ; Pixel Control
; Display Status bit field
HORTOG equ 0004h ;
VBLANK equ 0002h ;
SENSE equ 0001h
; Horizontal Sync Width Bit Field
HSYNCPOL_NEG equ 0020h ; negative polarity
HSYNCPOL_POS equ 0000h ; positive polarity
; Vertical Sync Width Bit Field
VSYNCPOL_NEG equ 0020h ; negative polarity
VSYNCPOL_POS equ 0000h ; positive polarity
; Display control bit field
DISPEN_NC equ 0000h ; no change
DISPEN_DISAB equ 0040h ; disable display, syncs, and refresh
DISPEN_ENAB equ 0020h ; enable display, syncs, and refresh
INTERLACE equ 0010h ; interlace enable bit
DBLSCAN equ 0008h ; double scan bit
MEMCFG_2 equ 0000h ; 2 CAS configuration
MEMCFG_4 equ 0002h ;
MEMCFG_6 equ 0004h ;
MEMCFG_8 equ 0006h ;
ODDBANKENAB equ 0001h ; Use alternate odd/even banks for
; each line
; Subsystem status register bits
_8PLANE equ 0080h ; 8 planes of memory installed
MONITORID_MASK equ 0070h ; Monitor ID mask
MONITORID_8503 equ 0050h ;
MONITORID_8507 equ 0010h ;
MONITORID_8512 equ 0060h ;
MONITORID_8513 equ 0060h ;
MONITORID_8514 equ 0020h ;
MONITORID_NONE equ 0070h ;
GPIDLE equ 0008h ; Processor idle bit, command queue empty
INVALIDIO equ 0004h ; Set when command written to full queue
; or the Pixel Data Transfer register was
; read when no data was available. This
; bit must be cleared prior to any other
; operation with RINVALIDIO bit
PICKFLAG equ 0002h ; This bit is set when a write inside the
; clipping rectangle is about to be made.
; You can clear it with RPICKFLAG
VBLNKFLAG equ 0001h ; This bit is set at the start of the
; vertical blanking period. It can only
; be cleared by setting RVBLNKFLG
; Subsystem Control Register bit field
GPCTRL_NC equ 0000h ; no change
GPCTRL_ENAB equ 4000h ; enable 8514
GPCTRL_RESET equ 8000h ; reset 8514/A and disable
; also flushes command queue
CHPTEST_NC equ 0000h ; no change
CHPTEST_NORMAL equ 1000h ; Enables synchronization between
; chips
CHPTEST_ENAB equ 2000h ; Disables synchronization. Use
; only as a diagnostic procedure
IGPIDLE equ 0800h ; Enable GPIDLE interrupt.
; Usually this is IRQ9 (SW IRQ2)
IINVALIDIO equ 0400h ; Enable invalid I/O interrupt
; Interrupt when subsystem status
; register INVALIDIO bit set
IPICKFLAG equ 0200h ; Interrupts the system when
; PICKFLAG in the subsystem
; status register goes high
IVBLNKFLAG equ 0100h ; Interrupts the system when
; VBLNKFLAG in Subsystem Status
; goes high
RGPIDLE equ 0008h ; Resets GPIDLE bit in subsystem
; status register
RINVALIDIO equ 0004h ; Resets INVALIDIO bit in
; Subsystem Status Register
RPICKFLAG equ 0002h ; Resets PICKFLAG in Subsystem
; Status Register
RVBLNKFLAG equ 0001h ; Resets VBLNKFLAG in Subsystem
; Status Register
; Current X, Y and Destination X, Y mask
COORD_MASK equ 07FFh ; coordinate mask (2047)
; Advanced Function Control Register bit field
CLKSEL equ 0004h ; 1 = 44.9 MHz clock, 0 = 25.175 MHz
DISSABPASSTHRU equ 0001h ; 0 = VGA pass through, 1 = 8514/A
; Graphics Processor Status Register
GPBUSY equ 0200h ; 1 when processor is busy in command
; and in data transfer
DATARDY equ 0100h ; 0 = no data ready to be read
; 1 = data ready for reading.
; used for Pixel Data Transfer reads
; Command Register
CMD_NOP equ 0000h ; do nothing
CMD_LINE equ 2000h ; Draw a line according to LINETYPE bit
; when LINETYPE = 1, bits 567 specify
; direction of vector with length
; stored in Major Axis Pixel Count
CMD_RECT equ 4000h ; Fast-Fill Rectangle accordign to
; PLANEMODE. Can read as well as write
; according to PCDATA and WRTDATA
CMD_RECTV1 equ 6000h ; Draws a rectangle vertically in
; columns starting at the upper left
; and working down
CMD_RECTV2 equ 8000h ; Like CMD_RECT1, except accesses 4
; pixels at a time horizontally rather
; than 1
CMD_LINEAF equ 0A000h ; Draw line for area fill. Only draws
; one pixel for each scan line crossed.
CMD_BITBLT equ 0C000h ; Copy rectangle on display and to/from
; PC memory through Pixel Data Transfer
; register.
CMD_OP_MSK equ 0E000h ; command mask
BYTSEQ equ 01000h ; Selects byte ordering for pixel data
; transfer and short-stroke vector
; transfer registers only. 0 = high
; byte first, low byte second, 1 =
; low byte first, high byte second.
_16BIT equ 00200h ; Affects Pixel Data Transfer and Short
; Stroke Vector Transfer registers.
; 0 = 8-bit access, 1 = 16-bit access
PCDATA equ 00100h ; 0 = drawing operations use 8514/A
; based data
; 1 = drawing operations wait for
; data to be written or read from
; the Pixel Data Transfer register
; before proceeding to the next
; pixel. Direction of transfer
; is based on WRTDATA
INC_Y equ 00080h ; Determines y direction of lines
; during line drawing when LINETYPE is
; cleared.
; 0 = UP, 1 = DOWN
YMAJAXIS equ 00040h ; Determines major axis when LINETYPE
; is 0.
; 0 = X is major axis, 1 = Y is major
; axis.
INC_X equ 00020h ; Determines direction of X when drawing
; lines when LINETYPE = 0
; 0 = right to left (negative X dir)
; 1 = left to right (positive X dir)
DRAW equ 00010h ; 0 = move only, no pixels drawn
; 1 = draw
LINETYPE equ 00008h ; Selects line drawing algorithm
; 0 = normal Bresenham line drawing
; 1 = vector drawing CMD_NOP = short
; stroke, CMD_LINE = long line
LASTPIX equ 00004h ; 0 = last pixel for lines and vectors
; drawn
; 1 = last pixel not drawn
PLANAR equ 00002h ; Access is Pixel at a time or Planar
; 0 = Pixel, 1 = Planar
WRTDATA equ 00001h ; 0 = read operation, 1 = write
; used for Pixel Data Transfer
; Short Stroke vector transfer register
; can also be used for command register when LINETYPE=1 and CMD_LINE
VECDIR_000 equ 0000h
VECDIR_045 equ 0020h
VECDIR_090 equ 0040h
VECDIR_135 equ 0060h
VECDIR_180 equ 0080h
VECDIR_225 equ 00A0h
VECDIR_270 equ 00C0h
VECDIR_315 equ 00E0h
SSVDRAW equ 0010h ; 0 = move position, 1 = draw vector
; and move
; Background MIX register
BSS_BKGDCOL equ 0000h ; use background color
BSS_FRGDCOL equ 0020h ; use foreground color
BSS_PCDATA equ 0040h ; PC data (via Pixel Data Transfer reg)
BSS_BITBLT equ 0060h ; All-Plane Copy
; Foreground MIX register
FSS_BKGDCOL equ 0000h ; use background color
FSS_FRGDCOL equ 0020h ; use foreground color
FSS_PCDATA equ 0040h ; PC data (via Pixel Data Transfer reg)
FSS_BITBLT equ 0060h ; All-Plane Copy
; Mixing applications
MIX_MASK equ 001Fh ; mask for mixing values
MIX_NOT_DST equ 0000h ; NOT Dst
MIX_0 equ 0001h ; All bits cleared
MIX_1 equ 0002h ; All bits set
MIX_DST equ 0003h ; Dst
MIX_LEAVE_ALONE equ 0003h ; Do nothing
MIX_NOT_SRC equ 0004h ; NOT Src
MIX_SRC_XOR_DST equ 0005h ; Src XOR Dst
MIX_XOR equ 0005h ;
MIX_NOT__SRC_XOR_DST equ 0006h ; NOT (Src XOR Dst)
MIX_XNOR equ 0006h ;
MIX_SRC equ 0007h ; Src
MIX_REPLACE equ 0007h ;
MIX_PAINT equ 0007h ;
MIX_NOT_SRC_OR_NOT_DST equ 0008h ; Not Src OR NOT Dst
MIX_NAND equ 0008h ;
MIX_NOT_SRC_OR_DST equ 0009h ; NOT Src OR Dst
MIX_SRC_OR_NOT_DST equ 000Ah ; Src OR NOT Dst
MIX_SRC_OR_DST equ 000Bh ; Src OR Dst
MIX_OR equ 000Bh ;
MIX_SRC_AND_DST equ 000Ch ; Src AND Dst
MIX_AND equ 000Ch
MIX_SRC_AND_NOT_DST equ 000Dh ; Src AND NOT Dst
MIX_NOT_SRC_AND_DST equ 000Eh ; NOT Src AND Dst
MIX_NOT_SRC_AND_NOT_DST equ 000Fh ; NOT Src AND NOT Dst
MIX_NOR equ 000Fh ; Src NOR Dst
MIX_MIN equ 0010h ; MINIMUM (Src, Dst)
MIX_DST_MINUS_SRC equ 0011h ; Dst - Src (with underflow)
MIX_SRC_MINUS_DST equ 0012h ; Src - Dst (with underflow)
MIX_PLUS equ 0013h ; Src + Dst (with overflow)
MIX_MAX equ 0014h ; MAXIMUM (Src, Dst)
MIX_HALF__DST_MINUS_SRC equ 0015h ; (Dst - Src) / 2 (with underflow)
MIX_HALF__SRC_MINUS_DST equ 0016h ; (Src - Dst) / 2 (with underflow)
MIX_AVERAGE equ 0017h ; (Src + Dst) / 2 (with overflow)
MIX_DST_MINUS_SRC_SAT equ 0018h ; (Dst - Src) (with saturate)
MIX_SRC_MINUS_DST_SAT equ 001Ah ; (Src - Dst) (with saturate)
MIX_PLUS_SAT equ 001Bh ; (Src + Dst) (with saturate)
MIX_HALF__DST_MINUS_SRC_SAT equ 001Ch ; (Dst - Src) / 2 (with sat)
MIX_HALF__SRC_MINUS_DST_SAT equ 001Eh ; (Src - Dst) / 2 (with sat)
MIX_AVERAGE_SAT equ 001Fh ; (Src + Dst) / 2 (with saturate)
; Memory control register
BUFSWP equ 0010h ; pseudo 8-plane on 4-plane board
VRTCFG_2 equ 0000h ; vertical memory configuration
VRTCFG_4 equ 0004h
VRTCFG_6 equ 0008h
VRTCFG_8 equ 000Ch
HORCFG_4 equ 0000h ; Horizontal memory configuration
HORCFG_5 equ 0001h
HORCFG_8 equ 0002h
HORCFG_10 equ 0003h
; Pixel Control Register
MIXSEL_FRGDMIX equ 0000h ; use foreground mix for all drawing
; operations
MIXSEL_PATT equ 0040h ; use fixed pattern to decide which
; mix setting to use on a pixel
MIXSEL_EXPPC equ 0080h ; PC Data Expansion. Use data from
; Pixel Transfer Register
MIXSEL_EXPBLT equ 00C0h ; Bits in source plane determine
; foreground or background MIX
; 0 = bkgd, 1 = frgd
COLCMPOP_F equ 0000h ; FALSE
COLCMPOP_T equ 0008h ; TRUE
COLCMPOP_GE equ 0010h ; Dst >= CC
COLCMPOP_LT equ 0018h ; Dst < CC
COLCMPOP_NE equ 0020h ; Dst != CC
COLCMPOP_EQ equ 0028h ; Dst == CC
COLCMPOP_LE equ 0030h ; Dst <= CC
COLCMPOP_GT equ 0038h ; Dst > CC
PLANEMODE equ 0004h ; Enables plane mode for area fill and
; single plane expansion
; The following code was written largely by Aaron Williams
; and largely mucked up by Jonathan Osuch
.DATA
TEMP_SIZE = 12
NUM_ENTRIES = 256
__temp_palette DB TEMP_SIZE DUP (?)
Gra_mode_ctl_sh dw ?
WD_enhance_mode_sh dw 0
extrn sxdots:word, sydots:word ; number of dots across and down
extrn dacbox:byte
extrn daccount:word ; count of entries in DAC table
extrn cpu:word ; CPU type 88, 186, etc.
extrn debugflag:word ; for debugging purposes
wdth dw 0 ; JCO 4/11/92
height dw 0
bppstatus dw 0 ; temporary status for bpp ; JCO 4/11/92
bpp4x640 db 0 ; flag for 4 bpp and 640x480 ; JCO 4/11/92
adexboard db 0 ; set to 1 when ADEX board
currentmode dw 0 ; points to current mode table
ati_enhance_mode dw 0 ; 1 for 800x600, 11h for 1280x1024
loadset dd 0C0000064h ; entries to bios jump table
setmode dd 0C0000068h ; modified later if rom is moved
ati_temp dw 0
; 8514/A initialization tables written by Aaron Williams
mode640 dw 2381h ; Western Digital Enhanced Mode Register
dw 0003h ; advanced function control
dw 5006h ; Multifunction control
dw 0063h ; Horizontal total
dw 004Fh ; Horizontal displayed
dw 0052h ; Horizontal sync start
dw 002Ch ; Horizontal sync width
dw 0418h ; Vertical total
dw 03BBh ; Vertical displayed
dw 03D2h ; Vertical sync start
dw 0022h ; Vertical sync width
dw 0023h ; Display control
mode1024 dw 2501h ; Western Digital Enhanced Mode Register
; I will later add options for 70hz mode,
; interlaced mode, etc. This is used only
; for Adex or compatible boards
; for 70 hz, change to 2581h
dw 0007h ; advanced function control
dw 5006h ; Multifunction control
dw 00A2h ; Horizontal total
dw 007Fh ; Horizontal displayed
dw 0083h ; Horizontal sync start
dw 0016h ; Horizontal sync width
dw 0660h ; Vertical total
dw 05FBh ; Vertical displayed
dw 0600h ; Vertical sync start
dw 0008h ; Vertical sync width
disp1024 dw 0023h ; Display control
; The 1280 mode is supported only on Adex boards. If anyone has any info on
; other boards capable of this mode, I'd like to add support.
mode1280 dw 2589h ; WD enhanced mode register
dw 0007h ; advanced function control
dw 5006h ; Multifunction control
dw 0069h ; Horizontal total
dw 004Fh ; Horizontal displayed
dw 0053h ; Horizontal sync start
dw 0009h ; Horizontal sync width
dw 0874h ; Vertical total
dw 07FFh ; Vertical displayed
dw 0806h ; Vertical sync start
dw 0003h ; Vertical sync width
dw 0023h ; Display control
; 4bpp mode added by JCO 4/5/92, 1024x4 same as 1024x8
mode640x4 dw 0000h ; Western Digital Enhanced Mode Register ????
dw 0003h ; advanced function control
dw 5002h ; Multifunction control ; This may need to be 5000h
dw 0063h ; Horizontal total
dw 004Fh ; Horizontal displayed
dw 0052h ; Horizontal sync start
dw 002Ch ; Horizontal sync width
dw 0830h ; Vertical total
dw 0779h ; Vertical displayed
dw 07A8h ; Vertical sync start
dw 0022h ; Vertical sync width
dw 0021h ; Display control ; This may need to be 0020h
.CODE VIDEO_TEXT
; This routine updates the 8514/A palette
; For modes with resolutions > 1024x768, a different DAC must be used.
; The ADEX board uses a high-speed Brooktree DAC which uses 24 bits per
; color instead of the usual 18 bits.
; The data is written out in 3 parts during vertical retrace to prevent snow.
; Normal 8514/A routine modified to slow down the spin, JCO 4/3/92
w8514hwpal proc near
mov si, offset dacbox
cld
; dac_w_index
mov dx, DAC_W_INDEX
mov al, 0 ;start at beginning of 8514a palette
out dx, al;
cmp wdth, 1024
jbe writedac
cmp adexboard, 1
je wbrooktree
writedac: ; rewritten to slow down the spin, JCO 4/11/92
mov cx, daccount
mov bx, 0 ;use bx to hold index into the dac
mov ax, 256
cpallp:
push ax
cmp ax, cx
jae dopass
mov cx, ax
dopass:
push cx
; wait for first vertical blank
mov dx, DISP_STAT
chkvblnk1: ;loop til vertical blank
in ax, dx ;read status register
test ax, VBLANK
jz chkvblnk1 ;set to 1 during vertical blank
; wait for screen to display
chkvblnk2: ;loop while screen displayed
in ax, dx ;read status register
test ax, VBLANK
jnz chkvblnk2 ;set to 0 during screen display
; wait for next vertical blank, make sure we didn't miss it
chkvblnk3: ;loop til vertical blank
in ax, dx ;read status register
test ax, VBLANK
jz chkvblnk3 ;set to 1 during vertical blank
; move the palette in dacbox
mov dx, DAC_DATA
cpall2:
outsb ;put red into 8514/a palette
outsb ;put green into 8514/a palette
outsb ;put blue into 8514/a palette
loop cpall2
pop cx
add bx, cx
mov dx, DAC_W_INDEX ;load next piece of palette
mov ax, bx
out dx, al
pop ax
sub ax, cx
jnz cpallp
sti
ret
wbrooktree: ; we go here for updating the Brooktree
mov cx, 256 ; output first 1/3 of data
cli
Wait_For_Vsync ; wait for vertical retrace
mov dx, 02EDh
pall1: ; the brooktree uses 8 bits instead of 6
lodsb
shl al, 2
out dx, al
loop pall1
sti
mov cx, 256 ; output second 1/3 of data
cli
Wait_For_Vsync ; wait for vertical retrace
mov dx, 02EDh
pall2:
lodsb
shl al, 2
out dx, al
loop pall2
sti
mov cx, 256 ; output third 1/3 of data
cli
Wait_For_Vsync ; wait for vertical retrace
mov dx, 02EDh
pall3:
lodsb
shl al, 2
out dx, al
loop pall3
sti
ret
w8514hwpal endp
; reopen8514hw turns off VGA pass through and enables the 8514/A display
reopen8514hw PROC near
cmp adexboard, 0
je enableati
mov dx, WD_ESCAPE_REG
in al, dx
mov si, currentmode
mov dx, WD_ENHANCED_MODE_REG
outsw
jmp enablegeneric
enableati:
cmp ati_enhance_mode, 0
je enablegeneric
mov ax, ati_enhance_mode ; load mode into shadow set 1 (lores)
call dword ptr [loadset]
mov ax, 1 ; set lores mode
call dword ptr [setmode]
ret
enablegeneric:
mov ax, [Gra_mode_ctl_sh] ; Read shadow register.
or ax, BIT_0_ON ; Set for HIRES mode
mov [Gra_mode_ctl_sh], ax ; Update shadow register.
Out_Port ADVFUNC_CNTL, ax
ret
reopen8514hw ENDP
; open8514hw initializes the 8514/A for drawing graphics. It test for the
; existence of an 8514/A first.
; CY set on error
open8514hw proc near
; Test for the existence of an 8514/A card by writing to and reading
; from the Error term register.
xor al, al
mov adexboard, al
call load8514dacbox ; load dacbox for 8514/A setup JCO 4/6/92
; Assume 8514/A present and reset it. Otherwise a locked up board
; would not appear as an 8514/A. JCO 4/3/92
; reset 8514/A subsystem
mov dx, SUBSYS_CNTL
mov ax, GPCTRL_RESET+CHPTEST_NORMAL ; Reset + Normal
out dx, ax
mov ax, GPCTRL_ENAB+CHPTEST_NORMAL ; Enable + Normal
out dx, ax
mov dx, ERR_TERM
mov ax, 5A5Ah ; output our test value
out dx, ax
jmp $+2 ; add slight delay
jmp $+2
in ax, dx
cmp ax, 5A5Ah
je Found_8514 ; jump if ok
stc ; set error if not found
ret
Found_8514:
; we need at least a 186 or better for rep outsw and stuff for speed.
; We won't support the 8086/8088, since it's *very* unlikely that
; anyone with an 8088 based machine would invest in an 8514/A
;
cmp [cpu], 88
jne GoodCPU
stc
ret
GoodCPU: ; JCO 5/8/92
mov bx, sxdots ; uncommented this section and made check
cmp bx, 640 ; for interlaced monitor vs non-interlaced
jbe monitor_ok ; any old monitor should work non-interlaced
mov dx, SUBSYS_STAT
in ax,dx
and ax, MONITORID_MASK
cmp ax, MONITORID_8514 ; do we need to interlace?
jz setinterlaced ; yes, jump
cmp ax, MONITORID_8507 ; do we need to interlace?
jz setinterlaced ; yes, jump
jmp monitor_ok ; use default non-interlaced mode
setinterlaced:
or disp1024, INTERLACE ; set interlace bit, JCO 5/8/92
monitor_ok:
mov bpp4x640, 0 ;clear flag for y value translation
mov dx, SUBSYS_STAT
in ax, dx
;************** debug 4bpp
cmp debugflag, 8514
jne notest
test ax, _8PLANE ;if not set, 4bpp anyway, don't change
jnz notest
xor ax, _8PLANE ;clear the 8bpp bit to test 4bpp
notest:
;**************
mov bppstatus, ax ;save the status for a while
test ax, _8PLANE ;is it 8 bits per pixel?
jnz plane8 ;yes, 1024K video memory
; no, only 512K video memory, 4 bits per pixel
mov ax, sxdots ; AX contains H resolution
; test if 640x480x4bpp
mov bpp4x640, 1 ;set flag for y value translation
mov si, offset mode640x4 ; SI = offset of register data
mov bx, 640 ; BX = X resolution
mov cx, 480 ; CX = Y resolution
mov wdth, bx ; store display width
mov height, cx ; store display height
cmp ax, 640 ; jump if this resolution is correct
jbe setupopen
; test if 1024x768x4bpp
mov bpp4x640, 0 ;clear flag for y value translation
mov si, offset mode1024
mov bx, 1024
mov cx, 768
mov wdth, bx
mov height, cx
cmp ax, 1024
jbe setupopen
stc ; oops, to high a resolution
ret
plane8:
mov ax, sxdots ; AX contains H resolution
; test if 640x480
mov si, offset mode640 ; SI = offset of register data
mov bx, 640 ; BX = X resolution
mov cx, 480 ; CX = Y resolution
mov wdth, bx ; store display width
mov height, cx ; store display height
cmp ax, 640 ; jump if this resolution is correct
jbe setupopen
; test if 800x600 (special ati ultra mode)
; si does not need to be set, everything is in eeprom
mov bx, 800
mov cx, 600
mov wdth, bx
mov height, cx
cmp ax, 800
jbe setupopen
; test if 1024x768
mov si, offset mode1024
mov bx, 1024
mov cx, 768
mov wdth, bx
mov height, cx
cmp ax, 1024
jbe setupopen
; must be 1280x1024
mov si, offset mode1280
mov bx, 1280
mov cx, 1024
mov wdth, bx
mov height, cx
setupopen:
; test for Western Digital Chipset
mov currentmode, si
mov dx, WD_ESCAPE_REG
in al, dx
mov ax, 6AAAh
mov dx, MAJ_AXIS_PCNT
out dx, ax
mov dx, WD_ESCAPE_REG ; enable enhanced mode for ADEX board
in al, dx
mov dx, MAJ_AXIS_PCNT ; if port 96E8 is between 3F00h and 2A00h we
in ax, dx ; have a WD board, else IBM/Other
cmp ax, 2A00h
jb ati_ultra
cmp ax, 3F00h
ja ati_ultra
; We must have a Western Digital chip set.
; May not be Adex.
; Future test to implement will be to write a pixel to X,Y location
; with X > 1024 and read it back to check for enough memory for 1280
; mode.
mov al, 1
mov adexboard, al ; set adex board
mov dx, WD_ESCAPE_REG ; program WD
in al, dx
mov dx, WD_ENHANCED_MODE_REG
outsw ; output the Western Digital
; enhanced mode register
mov [WD_enhance_mode_sh], ax ; keep a copy of it
jmp openOK
ibm_8514_step:
jmp ibm_8514
ati_ultra:
mov ati_enhance_mode, 0 ; make sure enhanced mode is clear
; check for ATI
mov dx, 52EEh ; ROM_ADDR_1 register
in ax, dx
mov ati_temp, ax ; temporary save
mov ax, 5555h
out dx, ax
Wait_If_HW_Busy ; make sure HW is not busy
mov dx, 52EEh ; ROM_ADDR_1 register
in ax, dx
cmp ax, 5555h
jne ibm_8514_step ; nope must be real 8514a
mov ax, 2A2Ah
out dx, ax
Wait_If_HW_Busy ; make sure HW is not busy
mov dx, 52EEh ; ROM_ADDR_1 register
in ax, dx
cmp ax, 2A2Ah
jne ibm_8514_step ; nope must be real 8514a
mov ax, ati_temp
out dx, ax ; restore ROM_ADDR_1 register
and ati_temp, 007Fh ; calculate the ROM base address
mov ax, 80h ; (ROM_ADDR_1 & 0x7F)*0x80 + 0xC000
mul ati_temp
add ax, 0C000h
mov word ptr loadset+2, ax
mov word ptr setmode+2, ax
mov es, ax
mov ax, es:4Ch ; get ati bios revision
cmp al, 1h
jl ibm_8514 ; revision level too low, can't do it
cmp ah, 3h
jl ibm_8514 ; revision level too low, can't do it
; everything appears okay
; get resolution, could be 800x600 or 1280x1024
mov ax, sxdots ; AX contains H resolution
cmp ax, 640
jbe ibm_8514 ; too low for 800x600
cmp ax, 800
jbe set_800x600 ; must be 800x600
cmp ax, 1024
jbe ibm_8514 ; too low for 1280x1024
cmp ax, 1280
jbe set_1280x1024 ; must be 1280x1024
jmp ibm_8514 ; too high
set_800x600:
mov ax, 1 ; load 800x600 into shadow set 1 (lores)
call dword ptr [loadset]
jc ibm_8514 ; didn't work, forget it
mov ax, 1 ; set lores mode
call dword ptr [setmode]
jc ibm_8514 ; didn't work, forget it
mov ati_enhance_mode, 1 ; save mode
jmp setplane8
set_1280x1024:
mov ax, 11h ; load 1280x1024 into shadow set 1 (lores)
call dword ptr [loadset]
jc ibm_8514 ; didn't work, forget it
mov ax, 1 ; set lores mode
call dword ptr [setmode]
jc ibm_8514 ; didn't work, forget it
mov ati_enhance_mode, 11h ; save mode
jmp setplane4 ; 4 bits/pixel
ibm_8514:
lodsw ; ignore WD enhanced mode register
cmp wdth, 1024 ; make sure the resolution isn't too high
jbe openOK
stc ; a *real* 8514/A cannot run higher than
ret ; 1024x768, so quit
openOK:
Wait_If_HW_Busy ; make sure HW is not busy
mov dx, ADVFUNC_CNTL
lodsw ; get Multifunction Control
mov Gra_mode_ctl_sh, ax ; keep a copy of it
out dx, ax
mov dx, MULTIFUNC_CNTL ; program multifunction control
outsw
mov dx, H_TOTAL ; program HTOTAL
outsw
mov dx, H_DISP ; program HDISPLAYED
outsw
mov dx, H_SYNC_STRT ; set start of HSYNC
outsw
mov dx, H_SYNC_WID ; set width of HSYNC signal
outsw
mov dx, V_TOTAL ; set vertical total
outsw
mov dx, V_DISP ; set vertical resolution
outsw
mov dx, V_SYNC_STRT ; set start of V Sync
outsw
mov dx, V_SYNC_WID ; set width of V Sync signal
outsw
mov dx, DISP_CNTL ; set the display control
outsw
mov ax, bppstatus ;get status again, push/pop doesn't work!
test ax, _8PLANE
jnz setplane8
; enable 4 bits per pixel
setplane4:
mov ax, 0Fh
mov dx, DAC_MASK
out dx, al
mov ax, 0FF0Fh
mov dx, WRT_MASK
out dx, ax
jmp doneset
setplane8:
; enable 8 bits per pixel
mov ax, 0FFh
mov dx, DAC_MASK
out dx, al
mov ax, 0FFFFh
mov dx, WRT_MASK
out dx, ax
doneset:
; Complete environment set up 3/20/92 JCO
Out_Port BKGD_MIX, <BSS_BKGDCOL or MIX_REPLACE> ;set mixes
; FRGD_MIX set below
; WRT_MASK set above
Out_Port MULTIFUNC_CNTL, <PIX_CNTL or 0h> ; clear lower bits
; 3/20/92 JCO
; set clipping
Wait_Till_FIFO FOUREMPTY ; wait for room in queue
mov dx, MULTIFUNC_CNTL
mov ax, T_SCISSORS
out dx, ax ; set top clip to 0
mov ax, cx
dec ax
or ax, B_SCISSORS
out dx, ax ; set bottom clip to maxy
mov ax, L_SCISSORS
out dx, ax ; set left clip to 0
mov ax, bx
dec ax
or ax, R_SCISSORS ; set right clip to maxx
out dx, ax
; clear screen
Wait_Till_FIFO SIXEMPTY ; wait for room in FIFO
mov dx, FRGD_MIX
mov ax, 0021h ; zero memory ?? why 21h and not 01h? JCO
out dx, ax
xor ax, ax
mov dx, CUR_X ; set start of rectangle to 0,0
out dx, ax
mov dx, CUR_Y
out dx, ax
mov ax, wdth
mov dx, MAJ_AXIS_PCNT
dec ax
out dx, ax ; set width of rectangle to draw
mov ax, height
mov dx, MULTIFUNC_CNTL
dec ax
out dx, ax ; set height of rectangle to draw
; Reset_MULTIFUNC_CNTL ; done above
mov dx, CMD
mov ax, 42F3h ; issue rect draw command
out dx, ax ; draw the rectangle
; Wait_Till_FIFO ONEEMPTY ; set write mask ** done above
; mov dx, WRT_MASK ; to include all
; mov ax, 00FFh ; bits
; out dx, ax
Wait_Till_FIFO THREEEMPTY ; set foreground to default
mov dx, FRGD_MIX
; mov ax, FSS_PCDATA + MIX_SRC
mov ax, FSS_FRGDCOL + MIX_SRC ;slightly faster to not use pcdata
;to draw the dots, JCO 4/12/92
out dx, ax
xor ax, ax
mov dx, CUR_X ; set X,Y back to 0,0
out dx, ax
mov dx, CUR_Y
out dx, ax
; enable palette
Wait_If_HW_Busy ; wait until HW is done
cmp adexboard, 1 ; if adex board, we must assume a brooktree
jne notadexdac ; dac at all resolutions > 1024x768
cmp wdth, 1024 ;
ja brooktree ; jmp if using special Brooktree RAMDAC
notadexdac:
; mov dx, 2EAh ; set palette mask ** done above
; mov al, 0FFh
; out dx, al
jmp paletteinitdone
brooktree: ; brooktree DAC requires special
mov dx, 2ECh ; configuration. This DAC is required
mov al, 04h ; for 1280x1024 resolution, and it is not
out dx, al ; totally compatible with the standard RAMDAC
mov dx, 2EAh
mov al, 0FFh ; This code enables the DAC for proper operation
out dx, al
mov dx, 2ECh
mov al, 05h
out dx, al
mov dx, 2EAh
mov al, 0h
out dx, al
mov dx, 2ECh
mov al, 06h
out dx, al
mov dx, 2EAh
mov al, 040h
out dx, al
paletteinitdone:
; push bx ; This works if another video mode is used first. JCO 4/9/92
; push cx ; Using load8514dacbox, above, sets the 8514/A palette.
; call w8514hwpal ; set 8514 palette
; pop cx
; pop bx
mov ax, bx
sub ax, sxdots ;save centering factor
shr ax, 1
mov xadj, ax
mov ax, cx
sub ax, sydots
shr ax, 1
mov yadj, ax
clc ; no errors
ret
open8514hw endp
;reopen8514hw proc near
; Return to 8514/A after VGA
; call enableHIRES
; ret
;reopen8514hw endp
fr85hwwdot proc near
; draws a pixel at cx,dx of color al
mov bx, dx ; temporary save of dx (y position)
push ax ; need to save ax register (color)
Wait_Till_FIFO FIVEEMPTY
pop ax
mov dx, FRGD_COLOR
out dx, ax
add cx, xadj
mov ax, cx
mov dx, CUR_X
out dx, ax ; set x position
mov ax, bx ; put y position into ax
add ax, yadj
;******* not needed by Graphics Ultra, may be needed by others.
;******* would only be needed in 640x480x16 mode, 512K video memory
; cmp bpp4x640, 1
; jne wdotnorm
; TRANSY ;flag set, translate y value
;wdotnorm:
mov dx, CUR_Y
out dx, ax ; set y position
; next, set up command register
Out_Port CMD, <CMD_NOP or LINETYPE or WRTDATA>
Out_Port SHORT_STROKE, <VECDIR_000 or SSVDRAW or 0> ; plot 1 pixel
ret
fr85hwwdot endp
fr85hwwbox proc near uses si
; copies a line of data from ds:si to the display from cx,dx to ax,dx
sub ax, cx ; delta is now in ax, 8514/a uses deltas
mov bx, ax ; temporary save
push dx ; need to save dx register (y value)
Wait_Till_FIFO SIXEMPTY
pop ax
add ax, yadj
;******* not needed by Graphics Ultra, may be needed by others.
;******* would only be needed in 640x480x16 mode, 512K video memory
; cmp bpp4x640, 1
; jne wboxnorm
; TRANSY ;flag set, translate y value
;wboxnorm:
mov dx, CUR_Y
out dx, ax ; y position
add cx, xadj
mov ax, cx
mov dx, CUR_X
out dx, ax ; x position
mov ax, bx
mov dx, MAJ_AXIS_PCNT
out dx, ax ; line length delta
Out_Port FRGD_MIX, <FSS_PCDATA or MIX_SRC> ;set mix
mov cx, bx ; number of pixels delta
inc cx ; number of bytes to move
shr cx, 1 ; number of words to move
jnc evn ; carry set if odd number of bytes
inc cx ; write last byte
evn:
Out_Port CMD, <CMD_LINE or LINETYPE or _16BIT or BYTSEQ or PCDATA \
or DRAW or WRTDATA or VECDIR_000>
cld
mov dx, PIX_TRANS
rep outsw
Out_Port FRGD_MIX, <FSS_FRGDCOL or MIX_SRC> ;reset mix
ret
fr85hwwbox endp
fr85hwrdot proc near
; Reads a single pixel (x,y = cx,dx). Color returned in ax
push dx ; need to save dx register (y value)
Wait_Till_FIFO FOUREMPTY
pop ax ; put y position into ax
add ax, yadj
;******* not needed by Graphics Ultra, may be needed by others.
;******* would only be needed in 640x480x16 mode, 512K video memory
; cmp bpp4x640, 1
; jne rdotnorm
; TRANSY ;flag set, translate y value
;rdotnorm:
mov dx, CUR_Y
out dx, ax ; set y position
mov ax, cx ; put x position into ax
add ax, xadj
mov dx, CUR_X
out dx, ax ; set x position
; next, set up command register
Out_Port CMD, <CMD_NOP or LINETYPE or PCDATA>
Out_Port SHORT_STROKE, <VECDIR_000 or SSVDRAW or 0> ; move to pixel
Wait_Till_Data_Avail ; make sure data is available to read
In_Port PIX_TRANS
ret
fr85hwrdot endp
fr85hwrbox proc near uses es
; copies a line of data from cx,dx to ax,dx to es:di
mov bx, ds ;set up string write
mov es, bx
sub ax, cx ; delta is now in ax, 8514/a uses deltas
mov bx, ax ; temporary save
push dx ; need to save dx register
Wait_Till_FIFO FOUREMPTY
pop ax ; put y value in ax
add ax, yadj
;******* not needed by Graphics Ultra, may be needed by others.
;******* would only be needed in 640x480x16 mode, 512K video memory
; cmp bpp4x640, 1
; jne rboxnorm
; TRANSY ;flag set, translate y value
;rboxnorm:
mov dx, CUR_Y
out dx, ax ; y position
add cx, xadj
mov ax, cx
mov dx, CUR_X
out dx, ax ; x position
mov ax, bx
mov dx, MAJ_AXIS_PCNT
out dx, ax ; line length delta
mov cx, bx ; number of pixels delta
inc cx ; number of bytes to move
shr cx, 1 ; number of words to move
jnc revn ; carry set if odd number of bytes
inc cx ; read last byte
revn:
Out_Port CMD, <CMD_LINE or LINETYPE or _16BIT or BYTSEQ or PCDATA \
or DRAW or VECDIR_000>
cld ; di is already set when routine is entered
Wait_Till_Data_Avail ; wait until data is available
mov dx, PIX_TRANS
rep insw
ret
fr85hwrbox endp
; enableVGA causes the VGA pass-through to be enabled.
; This was mostly written by Roger Brown, and optimized and updated by
; Aaron Williams
enableVGA PROC USES ds es si di
; disable DAC mask
mov al, 0
Out_Port_Byte DAC_MASK, al
Wait_For_Vsync
; use VGA lock up palette for Hi Res mode 8514/a display
xor bx, bx ; Initial palette entry
read_palette_loop:
mov di, OFFSET __temp_palette ; Buffer address
mov al, bl ; [1] VGA 3C8h register is byte
; register, use byte output only
mov dx, 3c8h ; VGA_DAC_W reg.
out dx, al
mov dx, 3c7h ; set VGA DAC read index
out dx, al ; any write change mode
mov cx, TEMP_SIZE ; Number of bytes to read each pass
mov dx, 3c9h ; VGA_DAC_DATA_REG
mov ax, ds ; Segment of _temp_palette[]
mov es, ax
cld
rep insb ; Read in the palette
; BX->start_index, CX->count, DS:DI->DWORD
Out_Port_Byte DAC_W_INDEX, bl
cli
cld
mov si, OFFSET __temp_palette ; Buffer address
mov dx, DAC_DATA
mov cx, (TEMP_SIZE ) ; Number of entries to write each pass
rep outsb ; update the DAC data
sti
mov cx, (TEMP_SIZE / 3)
add bx, cx
cmp bx, NUM_ENTRIES
jl read_palette_loop
; reading vga DAC mask and writing to 8514 DAC mask 02EA
mov dx, 3c6h
in al, dx
Out_Port_Byte DAC_MASK, al
; enable vga pass-through mode
mov ax, Gra_mode_ctl_sh ; Read shadow register.
; [2] No FIFO checking needed for
; 4AE8h register.
and ax, BIT_0_OFF ; Set for VGA pass-through mode.
mov Gra_mode_ctl_sh, ax
Out_Port ADVFUNC_CNTL, ax;
ret
enableVGA ENDP
close8514hw proc near
; Re-enables VGA pass-through.
cmp adexboard, 0
je close_notAdex ; Don't call enableVGA if not Adex, JCO 4/4/92
call enableVGA ; This seems to transfer the dac from
; the VGA to the 8514/A and then enable
; VGA mode!!!
mov si, offset mode1024
mov dx, WD_ESCAPE_REG ; program WD
in al, dx
mov dx, WD_ENHANCED_MODE_REG
outsw
close_notAdex:
cmp ati_enhance_mode, 0
je close_notati
mov ax, 0 ; load defaults into shadow sets
call dword ptr [loadset]
mov ax, 0 ; set VGA passthrough
call dword ptr [setmode]
close_notati:
mov dx, ADVFUNC_CNTL
mov ax, 6
out dx, ax ; enable VGA
ret
close8514hw endp
; This routine sets 320x200x256 VGA mode and then loads dacbox, JCO 4/11/92
load8514dacbox proc near uses es
mov ax,13h ; switch to 320x200x256 mode
int 10h
push ds ; ...
pop es ; ...
mov ax,1017h ; get the old DAC values
mov bx,0 ; (assuming, of course, they exist)
mov cx,256 ; ...
mov dx,offset dacbox ; ...
int 10h ; do it.
ret
load8514dacbox endp
END